use std::collections::HashMap;

/// 压缩内存句柄
#[derive(Debug, Clone)]
pub struct CompressedHandle {
    pub data_ptr: *mut u8,
    pub original_size: usize,
    pub compressed_size: usize,
    pub pattern_id: u32,
}

/// 内存压缩器
pub struct MemoryCompressor {
    pattern_cache: HashMap<u32, Vec<u8>>,
    total_compressed: usize,
    total_original: usize,
}

impl MemoryCompressor {
    pub fn new() -> Self {
        MemoryCompressor {
            pattern_cache: HashMap::new(),
            total_compressed: 0,
            total_original: 0,
        }
    }

    /// 压缩数据
    pub fn compress(&mut self, data: &[u8]) -> Option<CompressedHandle> {
        if data.is_empty() {
            return None;
        }

        // 简单的RLE压缩实现
        let compressed = self.simple_rle_compress(data);
        
        if compressed.len() < data.len() {
            let layout = std::alloc::Layout::from_size_align(compressed.len(), 8).unwrap();
            let ptr = unsafe { std::alloc::alloc(layout) };
            
            if !ptr.is_null() {
                unsafe {
                    std::ptr::copy_nonoverlapping(compressed.as_ptr(), ptr, compressed.len());
                }
                
                self.total_compressed += compressed.len();
                self.total_original += data.len();
                
                Some(CompressedHandle {
                    data_ptr: ptr,
                    original_size: data.len(),
                    compressed_size: compressed.len(),
                    pattern_id: 1, // 简化版本使用固定模式ID
                })
            } else {
                None
            }
        } else {
            None
        }
    }

    /// 解压数据
    pub fn decompress(&self, handle: &CompressedHandle) -> Option<Vec<u8>> {
        if handle.data_ptr.is_null() {
            return None;
        }

        let compressed = unsafe {
            std::slice::from_raw_parts(handle.data_ptr, handle.compressed_size)
        };

        Some(self.simple_rle_decompress(compressed, handle.original_size))
    }

    /// 释放压缩内存
    pub fn free_compressed(&mut self, handle: &CompressedHandle) {
        if !handle.data_ptr.is_null() {
            // 使用实际的压缩数据大小进行释放
            let layout = std::alloc::Layout::from_size_align(handle.compressed_size, 8).unwrap();
            unsafe { std::alloc::dealloc(handle.data_ptr, layout) };
            
            // 更新统计信息
            self.total_compressed = self.total_compressed.saturating_sub(handle.compressed_size);
            self.total_original = self.total_original.saturating_sub(handle.original_size);
        }
    }

    /// 获取压缩统计
    pub fn get_compression_stats(&self) -> CompressionStats {
        let ratio = if self.total_original > 0 {
            self.total_original as f64 / self.total_compressed as f64
        } else {
            1.0
        };

        CompressionStats {
            total_original: self.total_original,
            total_compressed: self.total_compressed,
            compression_ratio: ratio,
            patterns_cached: self.pattern_cache.len(),
        }
    }

    /// 简单的RLE压缩
    fn simple_rle_compress(&self, data: &[u8]) -> Vec<u8> {
        if data.is_empty() {
            return Vec::new();
        }

        let mut result = Vec::new();
        let mut count = 1;
        let mut current = data[0];

        for &byte in &data[1..] {
            if byte == current && count < 255 {
                count += 1;
            } else {
                result.push(count);
                result.push(current);
                current = byte;
                count = 1;
            }
        }

        result.push(count);
        result.push(current);
        result
    }

    /// 简单的RLE解压
    fn simple_rle_decompress(&self, data: &[u8], original_size: usize) -> Vec<u8> {
        let mut result = Vec::with_capacity(original_size);
        
        let mut i = 0;
        while i < data.len() && i + 1 < data.len() {
            let count = data[i] as usize;
            let value = data[i + 1];
            
            result.extend(std::iter::repeat(value).take(count));
            i += 2;
        }

        // 确保结果长度正确
        if result.len() > original_size {
            result.truncate(original_size);
        } else if result.len() < original_size {
            result.resize(original_size, 0);
        }

        result
    }
}

/// 压缩统计信息
#[derive(Debug, Clone)]
pub struct CompressionStats {
    pub total_original: usize,
    pub total_compressed: usize,
    pub compression_ratio: f64,
    pub patterns_cached: usize,
}

impl Default for MemoryCompressor {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_compression() {
        let mut compressor = MemoryCompressor::new();
        let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 3];
        
        if let Some(handle) = compressor.compress(&data) {
            assert!(handle.compressed_size <= handle.original_size);
            
            let decompressed = compressor.decompress(&handle).unwrap();
            assert_eq!(decompressed, data);
            
            compressor.free_compressed(&handle);
        }
    }

    #[test]
    fn test_compression_stats() {
        let mut compressor = MemoryCompressor::new();
        let data = vec![1, 1, 1, 1, 1];
        
        if compressor.compress(&data).is_some() {
            let stats = compressor.get_compression_stats();
            assert!(stats.compression_ratio >= 1.0);
        }
    }
}